#include "TThread.h"

TThread::TThread(void):
m_thread(0),
m_void(NULL)
{
	pthread_attr_init(&m_attr);
}

TThread::~TThread(void)
{
	pthread_attr_destroy(&m_attr);
	stop_run();

}
bool TThread::start_run( void * args  ,THREAD_ROUTINE fn  ,int stack_size  ,THREAD_DETACH_STATUS status ,THREAD_BIND_STATUS bind_status ,int policy , int priority )
{
	m_void = args ; //ÉèÖÃ´«ÈëµÄ²ÎÊý
	pthread_attr_setscope(&m_attr, bind_status); //°ó¶¨ÉèÖÃ
	pthread_attr_setdetachstate( &m_attr, status );	//·ÖÀëÉèÖÃ
	pthread_attr_setstacksize( &m_attr, stack_size ); //ÉèÖÃ¶ÑÕ»´óÐ¡

	set_priority( priority ,policy );

	THREAD_HANDLE thread_id = 0 ;
	THREAD_ROUTINE fn_runtine = fn ;
	int result ;
	if ( fn == NULL )
	{
		fn_runtine = thread_func ;
		result =   pthread_create( & thread_id,  &m_attr , fn_runtine, this ) ;
	}
	else
	{
           result =   pthread_create( & thread_id,  &m_attr , fn_runtine, m_void ) ;
	}

	m_thread = result == 0 ? thread_id : 0 ;
	return result == 0 ;
}
//ÉèÖÃÏß³ÌÓÅÏÈ¼¶
bool TThread::set_priority( int priority ,int policy  )
{
	/************************************************************************/
	/* SCHED_OTHERÊÇ²»Ö§³ÖÓÅÏÈ¼¶Ê¹ÓÃµÄ£¬¶øSCHED_FIFOºÍSCHED_RRÖ§³ÖÓÅÏÈ¼¶µÄÊ¹ÓÃ£¬ËûÃÇ·Ö±ðÎª1ºÍ99£¬ÊýÖµÔ½´óÓÅÏÈ¼¶Ô½¸ß¡£
	ÏÈÈëÏÈ³ö²ßÂÔ (SCHED_FIFO)¡¢Ñ­»·²ßÂÔ (SCHED_RR) ºÍ×Ô¶¨Òå²ßÂÔ (SCHED_OTHER):SCHED_OTHERÈ±Ê¡
	*/
	/************************************************************************/
	int rs = pthread_attr_getschedpolicy( &m_attr, &policy );
	//assert( rs == 0 );
	if ( policy == SCHED_FIFO ) //²»Ö§³ÖÓÅÏÈ¼¶Ê¹ÓÃµÄ
	{
		return false ;
	}
	rs = pthread_attr_setschedpolicy( &m_attr, policy ); //ÉèÖÃ¸ß¶È²ßÂÔ
	//assert( rs == 0 );
	//ÉèÖÃÏß³ÌÓÅÏÈ¼¶,Ä¬ÈÏ0

	//int priority = sched_get_priority_max( policy ); //×î´óÓÅÏÈ¼¶
	//assert( priority != -1 );

	//priority = sched_get_priority_min( policy ); //×îÐ¡ÓÅÏÈ¼¶
	//assert( priority != -1 );


	sched_param param;
	pthread_attr_getschedparam( &m_attr ,&param );
	param.sched_priority = priority ;
	pthread_attr_setschedparam( &m_attr, &param);
	return true ;


}
//Ïß³ÌÄÚ²¿ÔËÐÐµÄº¯Êý
void * TThread::thread_func( void * object )
{
	TThread * _this = ( TThread * ) object; //±¾Éí¶ÔÏñ
	//pthread_detach(pthread_self()); //ÉèÖÃ·ÖÀëµÄÏß³Ì
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);		 //ÉèÖÃÄÜÈ¡Ïû
	//ÉèÖÃ³ÉÁ¢¼´È¡ÏûÄ£Ê½
	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);

	//ÔËÐÐ¸Ãº¯Êý£¬²¢´«ÈëÄ³¸ö²ÎÊý
	_this->run( _this->m_void ) ;

	pthread_exit((void*)NULL);
	//printf(" thread is exit \n");
	return NULL;
}
//Í£Ö¹Ïß³Ì
void TThread::stop_run()
{
	try
	{
		if ( m_thread != 0 )
		{
			pthread_cancel( m_thread );
			m_thread = 0 ;
		}
	}
	catch (...)
	{

	}
}
